package com.singbon.server.config;
import com.singbon.server.security.CustomAuthenticationProvider;
import com.singbon.server.security.CustomUserDetailsService;
import com.singbon.server.util.VerifyServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
/**
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  @Resource
  private DataSource dataSource;
  @Resource
  private CustomUserDetailsService userDetailsService;
  @Resource
  private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;
  @Resource
  private CustomAuthenticationProvider customAuthenticationProvider;
  @Resource
  private CustomLogoutSuccessHandler customLogoutSuccessHandler;
  @Resource
  private CustomLoginAuthenticationSuccessHandler customLoginAuthenticationSuccessHandler;
  @Override
  protected void configure(AuthenticationManagerBuilder auth) {
    // 指定 provider
    auth.authenticationProvider(customAuthenticationProvider);
    auth.authenticationProvider(authenticationProvider());
  }
  /**
   * 注入验证码servlet
   */
  @Bean
  public ServletRegistrationBean<VerifyServlet> indexServletRegistration() {
    ServletRegistrationBean<VerifyServlet> registration = new ServletRegistrationBean<>(new VerifyServlet());
    registration.addUrlMappings("/getVerifyCode");
    return registration;
  }
  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }
  @Bean
  public PersistentTokenRepository persistentTokenRepository() {
    JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
    tokenRepository.setDataSource(dataSource);
    // 如果token表不存在使用下面语句可以初始化该表 若存在会报错:tokenRepository.setCreateTableOnStartup(true)
    return tokenRepository;
  }
  @Bean
  public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setUserDetailsService(userDetailsService);
    authenticationProvider.setPasswordEncoder(passwordEncoder());
    authenticationProvider.setHideUserNotFoundExceptions(false);
    return authenticationProvider;
  }
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.requestMatchers()
      //
      .antMatchers("/oauth/**", "/login/**", "/logout/**", "/zk0vxsxuq7")
      //
      .and().authorizeRequests()
      //
      .antMatchers("/oauth/**")
      //
      .authenticated().and().formLogin()
      // 登录页面
      .loginPage("/login").permitAll()
      // 登录失败Url
      .failureUrl("/login?error=true")
      // .successHandler(customLoginAuthenticationSuccessHandler)
      //
      .authenticationDetailsSource(authenticationDetailsSource)
      //
      // .and().logout().logoutSuccessHandler(customLogoutSuccessHandler)
      .and().logout()
      //
      //      //
      //.logoutSuccessUrl("/index")
      // .logoutUrl("/logout")
      //
      .deleteCookies("JSESSIONID", "xb-card-set-user", "companyName", "1")
      //      //
      .logoutSuccessHandler(customLogoutSuccessHandler)
      //
      .deleteCookies("JSESSIONID", "xb-card-set-user", "xb-**", "companyName")
      // 无效会话
      .invalidateHttpSession(true)
      // 清除身份验证
      .clearAuthentication(true).permitAll().and()
      //
      .rememberMe().tokenRepository(persistentTokenRepository())
      // 有效时间：单位s
      .tokenValiditySeconds(86400)
      //
      .userDetailsService(userDetailsService);
    // http.formLogin().successForwardUrl("http://www.baidu.com");
    //
    http.csrf().disable();
  }
  @Override
  public void configure(WebSecurity web) throws Exception {
    // 设置拦截忽略文件夹，可以对静态资源放行
    web.ignoring().antMatchers("/static/**");
  }
}
